#include "crc.h"

namespace infrastructure {
namespace utilities {

uint16_t ModbusCRC::crc16(uint8_t* buffer, uint16_t buffer_length)
{
    uint8_t crc_hi = 0xFF;
    uint8_t crc_lo = 0xFF;
    unsigned int i;

    while (buffer_length--) {
        i = crc_hi ^ *buffer++;
        crc_hi = crc_lo ^ table_crc_hi.at(i);
        crc_lo = table_crc_lo.at(i);
    }

    return uint16_t(crc_hi << BYTE_ | crc_lo);
}

uint16_t ModbusCRC::crc16_ccitt_calc(const uint8_t* data, uint16_t n)
{
    uint16_t crc = 0xFFFF;
    const uint8_t* theData = data;

    while (n--) {
        crc = (crc >> 8) ^ ccitt_table.at((crc ^ *theData++) & 0xFF);
    }

    return crc;
}

uint16_t ModbusCRC::crc16_ccitt_calc_false(const uint8_t* data, uint16_t n)
{
    uint16_t crc = 0xFFFF;
    const uint8_t* theData = data;

    while (n--) {
        crc = (crc << 8) ^ ccitt_false_table.at((crc >> 8 ^ *theData++) & 0xFF);
    }

    return crc;
}

} // namespace utilities
} // namespace infrastructure
